home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / FPGAWKII.ZIP / JTAG.C < prev    next >
C/C++ Source or Header  |  1995-04-10  |  39KB  |  1,211 lines

  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include <stdlib.h>
  4. #include <stdarg.h>
  5. #include <conio.h>
  6. #include <malloc.h>
  7. #include "jtag.h"
  8.  
  9.  
  10.  
  11. /* BITSTREAM-HANDLING SUBROUTINES */
  12.  
  13. /*
  14.  * RTN AllocBits: allocates a bitstream containing at least NumBits.
  15.  */
  16. bitstream *AllocBits( int NumBits )
  17.     {
  18.     int i, WordLength, NumWords;
  19.     bitstream *bits;
  20.  
  21.     /* compute the number of bitstream words needed to store the
  22.        requested number of bits */
  23.     WordLength = 8 * sizeof(bitstream) / sizeof(char);
  24.     NumWords = (NumBits-1)/WordLength + 1;
  25.  
  26.     /* let's see if we can allocate the bitstream storage */
  27.     if( (bits=NEWV(bitstream, NumWords)) == NULL )
  28.         {
  29.         /* Oops!  Guess not! */
  30.         fprintf( stderr, "Out of memory; can't create bitstream\n" );
  31.         assert(0==1); /* this will cause an abort */
  32.         }
  33.  
  34.     /* otherwise, we have the storage so we need to initialize it */
  35.     for( i=0; i<NumWords; i++ )
  36.         bits[i] = 0;  /* make it all zeroes */
  37.  
  38.     return( bits );  /* return a pointer to the bitstream storage */
  39.     }
  40.  
  41. /*
  42.  * RTN FreeBits: free the storage used by a bitstream.
  43.  */
  44. void FreeBits( bitstream *bits )
  45.     {
  46.     FREE( bits );
  47.     }
  48.  
  49. /*
  50.  * RTN GetBit: gets the value of a bit from a bitstream.
  51.  */
  52. unsigned int GetBit( bitstream *bits, int i )
  53.     {
  54.     int WordLength, WordIndex, BitIndex;
  55.  
  56.     /* calculate the number of bits in a bitstream data word
  57.        and use this to calculate what word and bit position in
  58.        that word the requested bit lies in. */
  59.     WordLength = 8 * sizeof(bitstream) / sizeof(char);
  60.     WordIndex  = i / WordLength;
  61.     BitIndex   = i % WordLength;
  62.  
  63.     /* now get the word and shift it so the requested bit is in the LSB.
  64.        Then mask off the reset and return just a 1 or a 0. */
  65.     return (unsigned int)((bits[WordIndex]>>BitIndex) & 1L);
  66.     }
  67.  
  68. /*
  69.  * RTN SetBit: sets the value of a bit in a bitstream
  70.  */
  71. void SetBit( bitstream *bits, int i, int val )
  72.     {
  73.     int WordLength, WordIndex;
  74.     bitstream BitMask;
  75.  
  76.     /* calculate the number of bits in a bitstream data word
  77.        and use this to calculate what word the requested bit lies in
  78.        and to generate a bitmask to mask off that bit. */
  79.     WordLength = 8 * sizeof(bitstream) / sizeof(char);
  80.     WordIndex = i / WordLength;
  81.     BitMask = 1L << (i % WordLength);
  82.  
  83.     /* now use the bitmask to force the requested bit to zero */
  84.     bits[WordIndex] &= ~BitMask;
  85.     /* and then set the requested bit to one if that's needed.
  86.        Otherwise leave it at zero. */
  87.     if( val )
  88.         bits[WordIndex] |= BitMask;
  89.     }
  90.  
  91. /*
  92.  * RTN CmpBits: mask two bitstreams and then XOR them.
  93.  *
  94.  * This routine compares selected bits of two bitstreams of the same
  95.  * length and places the XOR of them into a result bitstream.
  96.  * Any 1 bits in the result indicate places where the bitstreams differ.
  97.  */
  98. void CmpBits( int length, bitstream *b1, bitstream *b2,
  99.           bitstream *mask, bitstream *result )
  100.     {
  101.     int i, WordLength, WordIndex, MaxWord;
  102.  
  103.     /* compute the number of bitstream data words in the bitstreams */
  104.     WordLength = 8 * sizeof(bitstream) / sizeof(char);
  105.     MaxWord = (length+WordLength) / WordLength;
  106.  
  107.     /* XOR the bitstreams and store a 1 in the result anywhere the
  108.        two bitstreams differ and the mask is non-zero. */
  109.     for( i=0; i<MaxWord; i++ )
  110.         result[i] = (b1[i] ^ b2[i]) & mask[i];
  111.     }
  112.  
  113. /*
  114.  * RTN PrintBits: prints a bitstream to the standard output.
  115.  */
  116. void PrintBits( bitstream *bits, int length )
  117.     {
  118.     int i;
  119.  
  120.     /* start printing with the MSB which is stored at the
  121.        end of the bitstream.  Then work your way to the beginning. */
  122.     for( i=length-1; i>=0; i-- )
  123.         printf( "%c", GetBit(bits,i) ? '1':'0' );
  124.     printf( "\n" );
  125.     }
  126.  
  127.  
  128.  
  129. /* LOW-LEVEL PRINTER PORT SUBROUTINES */
  130.  
  131. /* We have to store the value we are currently outputing
  132.    through the parallel port since we can't reliably read it back. */
  133. static int OutPortValue=0xffff;
  134.  
  135. /* We may want to delay the transitions of signals through the
  136.    printer port if we are going too fast for reliable data transfer. */
  137. static int PortDelay=0;  /* start off with the maximum speed */
  138.  
  139. /* Here we will store the output and input addresses for the printer port. */
  140. static int OutPort=0;  /* the 0 address will alert us that these */
  141. static int InPort =0;  /* addresses are not initialized yet */
  142.  
  143. /*
  144.  * RTN SelectPort: select the printer port the JTAG signals go thru.
  145.  *
  146.  * Pass in either 1, 2, or 3 since most PCs support up to three
  147.  * printer ports.  The subroutine will warn you if you pick a
  148.  * non-existent port.
  149.  */
  150. void SelectPort( int PortNum )
  151.     {
  152.     int PortAddresses[4];   /* storage for the printer port addresses */
  153.  
  154.     PortAddresses[3] = 0;  /* store a dummy, non-existent port address
  155.                   in the final location of the array */
  156.  
  157.     if( PortNum<1 || PortNum>3 )
  158.         PortNum = 4;  /* invalid port #, so set to dummy port # */
  159.  
  160.     /* get the parallel port addresses stored in memory
  161.        starting at memory address 0x408 and move them to the
  162.        PortAddresses array.  Move the only the first six bytes so the final
  163.        entry in PortAddresses will still be zero. */
  164.     _asm{
  165.         mov ax,0x0
  166.         mov es,ax
  167.         mov bx,es:0x408
  168.         mov PortAddresses[0],bx
  169.         mov bx,es:0x40a
  170.         mov PortAddresses[2],bx
  171.         mov bx,es:0x40c
  172.         mov PortAddresses[4],bx
  173.     }
  174.  
  175.     /* now get the port I/O address for the requested printer port # */
  176.     OutPort = PortAddresses[PortNum-1];
  177.     InPort  = OutPort+1; /* the input address is always at the
  178.                 output address + 1 */
  179.  
  180.     /* the requested printer port doesn't exist if the
  181.        port address is 0 */
  182.     if( OutPort==0 )
  183.         {
  184.         fprintf( stderr, "The requested printer port does not exist!\n" );
  185.         assert(0==1);
  186.         }
  187.     }
  188.  
  189. /*
  190.  * RTN PortWait: delay for letting the output port signals settle.
  191.  */
  192. void PortWait( void )
  193.     {
  194.     int i;
  195.     for( i=PortDelay; i>0; i-- ) ;
  196.     }
  197.  
  198. /*
  199.  * RTN SetPortDelay: sets the time for letting the printer port settle.
  200.  */
  201. void SetPortDelay( int delay )
  202.     {
  203.     PortDelay = delay;
  204.     }
  205.  
  206. /*
  207.  * RTN OutToPort: output a value to the selected printer port.
  208.  */
  209. void OutToPort( int val )
  210.     {
  211.     /* if a valid printer port has not been selected, then we'll
  212.        select printer port 1 by default */
  213.     if( OutPort==0 )
  214.         SelectPort(1);
  215.  
  216.     /* output the value to the printer port and save the value
  217.        that is being put out */
  218.     outp( OutPort, val );
  219.     OutPortValue = val;
  220.  
  221.     /* {
  222.     bitstream b = OutPortValue;
  223.     PrintBits( &b, 32 );
  224.     } */
  225.  
  226.     /* insert a delay after the output value is changed */
  227.     PortWait();
  228.     }
  229.  
  230. /*
  231.  * RTN GetOutportValue: get the value currently being output on the
  232.  *                      printer port.
  233.  */
  234. int GetOutPortValue( void )
  235.     {
  236.     return OutPortValue;
  237.     }
  238.  
  239. /*
  240.  * RTN InFromPort: return a value from the selected printer port.
  241.  */
  242. int InFromPort( void )
  243.     {
  244.     /* if a valid printer port has not been selected, then we'll
  245.        select printer port 1 by default */
  246.     if( InPort==0 )
  247.         SelectPort(1);
  248.  
  249.     /* read the value from the status portion of the selected
  250.        printer port and return it */
  251.     return( inp( InPort) );
  252.     }
  253.  
  254.  
  255. /* TAP INTERFACE SUBROUTINES */
  256.  
  257. /* PC parallel port assignments to TAP pins */
  258. /* Remember!  TDO is the bit we put OUT from the PC printer port
  259.    to the TDI pin of the attached chip.  TDI is the bit we read
  260.    IN from the TDO pin of the attached chip.  In other words, the
  261.    names refer to the simulated TAP of the PC printer port, not to
  262.    the TAP of the attached chip. */
  263. #define TCKBIT          0
  264. #define TMSBIT          1
  265. #define TDOBIT          6
  266. #define TDIBIT          7
  267.  
  268. /*
  269.  * RTN SetPortBit: sets a bit of the port to a given value
  270.  */
  271. void SetPortBit( int bit, int val )
  272.     {
  273.     /* create a masking pattern for the bit */
  274.     unsigned int mask = 1<<bit;
  275.  
  276.     /* set the bit value to 0 */
  277.     int NewValue = GetOutPortValue() & ~mask;
  278.  
  279.     /* now set it to 1 if the val is non-zero */
  280.     if( val )
  281.         NewValue |= mask;
  282.  
  283.     /* now output the updated port value */
  284.     OutToPort( NewValue );
  285.     }
  286.  
  287. /*
  288.  * RTN GetPortBit: gets the value (0 or 1) of a bit of the port.
  289.  */
  290. unsigned int GetPortBit( int bit )
  291.     {
  292.     return (GetOutPortValue()>>bit) & 1;
  293.     }
  294.  
  295. /*
  296.  * RTN SetTMSValue: sets the value of the TMS bit on the TAP.
  297.  */
  298. void SetTMSValue( int val )
  299.     {
  300.     SetPortBit( TMSBIT, val );
  301.     }
  302.  
  303. /*
  304.  * RTN GetTMSValue: returns the value of the TMS bit on the TAP.
  305.  */
  306. unsigned int GetTMSValue( void )
  307.     {
  308.     return GetPortBit( TMSBIT );
  309.     }
  310.  
  311. /*
  312.  * RTN SetTDOValue: sets the value of the TDO bit on the JTAG port.
  313.  */
  314. void SetTDOValue( int val )
  315.     {
  316.     SetPortBit( TDOBIT, val );
  317.     }
  318.  
  319. /*
  320.  * RTN GetTDOValue: gets the value of the TDO bit on the JTAG Port
  321.  */
  322. unsigned int GetTDOValue( void )
  323.     {
  324.     return GetPortBit( TDOBIT );
  325.     }
  326.  
  327. /*
  328.  * RTN GetTDIValue: gets the value of the TDI bit from the input port
  329.  *                  which is fed from the TDO bit of the TAP port of the
  330.  *                  attached chip.
  331.  */
  332. unsigned int GetTDIValue( void )
  333.     {
  334.     return ((InFromPort()>>TDIBIT) & 1) ^ 1;
  335.     }
  336.  
  337. /*
  338.  * RTN GetTCKValue: gets the value of the TCK bit on the output port.
  339.  */
  340. unsigned int GetTCKValue( void )
  341.     {
  342.     return GetPortBit( TCKBIT );
  343.     }
  344.  
  345. /*
  346.  * RTN SetTCKValue: sets the value of the TCK bit on the output port.
  347.  */
  348. void SetTCKValue( int val )
  349.     {
  350.     SetPortBit( TCKBIT, val );
  351.     }
  352.  
  353. /*
  354.  * RTN JTAGTraceOnOff: enables/disables the trace of TAP signals coming
  355.  *                     out the printer port.
  356.  */
  357. static int JTAGTraceFlag = 0; /* start up with trace disabled */
  358. JTAGTraceOnOff( int OnOff )
  359.     {
  360.     JTAGTraceFlag = OnOff;
  361.     }
  362.  
  363. /*
  364.  * RTN PulseTCK: put a pulse on the TCK pin by toggling TCK twice.
  365.  */
  366. char *GetTAPStateText(); /* a declaration so we can use this routine */
  367. void PulseTCK( void )
  368.     {
  369.     /* get the original value of TCK */
  370.     int OldTCK = GetTCKValue();
  371.  
  372.     if( JTAGTraceFlag )
  373.         printf( "%s\t%1d %1d %1d\n", GetTAPStateText(),
  374.             GetTMSValue(), GetTDOValue(), GetTDIValue() );
  375.  
  376.     /* now toggle it to its opposite value ... */
  377.     SetTCKValue( OldTCK ^ 1 );
  378.     /* and then return it to its original value */
  379.     SetTCKValue( OldTCK );
  380.  
  381.     /* now make a check that TCK is 0.  This is the normal
  382.        quiescent value for our system. */
  383.     assert( OldTCK==0 );
  384.     }
  385.  
  386. /*
  387.  * RTN JTAGPortInit: initialize the JTAG port output value.
  388.  */
  389. void JTAGPortInit( void )
  390.     {
  391.     SetTMSValue(1);
  392.     SetTCKValue(0);
  393.     HardTAPReset();
  394.     }
  395.  
  396.  
  397.  
  398. /* TAP CONTROLLER TRANSITION SUBROUTINES */
  399.  
  400. /* TAP controller state definitions */
  401. typedef enum
  402.      {
  403.     TestLogicReset, RunTestIdle,
  404.     SelectDRScan,   SelectIRScan,
  405.     CaptureDR,      CaptureIR,
  406.     ShiftDR,        ShiftIR,
  407.     Exit1DR,        Exit1IR,
  408.     PauseDR,        PauseIR,
  409.     Exit2DR,        Exit2IR,
  410.     UpdateDR,       UpdateIR
  411.      } JTAGState;
  412.  
  413. #define NumTAPStates  16  /* number of TAP controller states */
  414.  
  415. /* This variable records the current state of TAP controller */
  416. static JTAGState CurrentTAPState = TestLogicReset;
  417.  
  418. /* The following array stores the transition table for the TAP
  419.    controller.  It tells us what the next state will be by placing the
  420.    current state code in the first index and the value of
  421.    the TMS input in the second index.                               */
  422. static JTAGState NextTAPState[NumTAPStates][2] =
  423.     {
  424.       /* TMS=0 */           /* TMS=1 */         /* current TAP state */
  425.     { RunTestIdle,        TestLogicReset },     /* TestLogicReset */
  426.     { RunTestIdle,        SelectDRScan   },     /* RunTestIdle    */
  427.     { CaptureDR,          SelectIRScan   },     /* SelectDRScan   */
  428.     { CaptureIR,          TestLogicReset },     /* SelectIRScan   */
  429.     { ShiftDR,            Exit1DR        },     /* CaptureDR      */
  430.     { ShiftIR,            Exit1IR        },     /* CaptureIR      */
  431.     { ShiftDR,            Exit1DR        },     /* ShiftDR        */
  432.     { ShiftIR,            Exit1IR        },     /* ShiftIR        */
  433.     { PauseDR,            UpdateDR       },     /* Exit1DR        */
  434.     { PauseIR,            UpdateIR       },     /* Exit1IR        */
  435.     { PauseDR,            Exit2DR        },     /* PauseDR        */
  436.     { PauseIR,            Exit2IR        },     /* PauseIR        */
  437.     { ShiftDR,            UpdateDR       },     /* Exit2DR        */
  438.     { ShiftIR,            UpdateIR       },     /* Exit2IR        */
  439.     { RunTestIdle,        SelectDRScan   },     /* UpdateDR       */
  440.     { RunTestIdle,        SelectDRScan   },     /* UpdateIR       */
  441.     };
  442.  
  443. /*
  444.  * RTN TAPStateToText: converts the TAP controller state into its
  445.  *                     textual name.
  446.  */
  447. char *TAPStateToText( JTAGState TAPState )
  448.     {
  449.     switch( TAPState )
  450.         {
  451.         case TestLogicReset:  return "Test-Logic-Reset";
  452.         case RunTestIdle:     return "Run-Test/Idle";
  453.         case SelectDRScan:    return "Select_DR-Scan";
  454.         case SelectIRScan:    return "Select_IR-Scan";
  455.         case CaptureDR:       return "Capture-DR";
  456.         case CaptureIR:       return "Capture-IR";
  457.         case ShiftDR:         return "Shift-DR";
  458.         case ShiftIR:         return "Shift-IR";
  459.         case Exit1DR:         return "Exit1-DR";
  460.         case Exit1IR:         return "Exit1-IR";
  461.         case PauseDR:         return "Pause-DR";
  462.         case PauseIR:         return "Pause-IR";
  463.         case Exit2DR:         return "Exit2-DR";
  464.         case Exit2IR:         return "Exit2-IR";
  465.         case UpdateDR:        return "Update-DR";
  466.         default:
  467.         case UpdateIR:        return "Update-IR";
  468.         }
  469.     }
  470.  
  471. /*
  472.  * RTN HardTAPReset: guarantees the TAP controller is in
  473.  *                   Test-Logic-Reset state.
  474.  */
  475. void HardTAPReset( void )
  476.     {
  477.     CurrentTAPState = TestLogicReset;
  478.  
  479.     /* the TAP controller will always be reset by raising TMS to 1
  480.        and then pulsing the TCK five times */
  481.     SetTMSValue(1);
  482.     PulseTCK();
  483.     PulseTCK();
  484.     PulseTCK();
  485.     PulseTCK();
  486.     PulseTCK();
  487.     }
  488.  
  489. /*
  490.  * RTN UpdateTAPState: use the current TAP controller state and TMS
  491.  *                     bit to compute the next TAP controller state.
  492.  *
  493.  * This routine keeps the copy of the TAP controller state in the
  494.  * program up-to-date with the TAP controller state in the chip
  495.  * (we hope).
  496.  */
  497. void UpdateTAPState( void )
  498.     {
  499.     CurrentTAPState = NextTAPState[ CurrentTAPState ][ GetTMSValue() ];
  500.     }
  501.  
  502. char *GetTAPStateText( void )
  503.     {
  504.     return TAPStateToText(CurrentTAPState);
  505.     }
  506.  
  507. /*
  508.  * RTN GotoNextTAPState: sets the TMS line to the appropriate value
  509.  *            such that the next TCK pulse will move the TAP controller
  510.  *            to the requested NextState.
  511.  *
  512.  * If the new state of the TAP controller doesn't match the requested
  513.  * state, the subroutine will cause the program to abort.
  514.  */
  515. char *TAPStateToText( JTAGState s );
  516.  
  517. void GotoNextTAPState( JTAGState NextState )
  518.     {
  519.     /* determine the correct TMS value to move to the desired state */
  520.     if( NextTAPState[CurrentTAPState][0] == NextState )
  521.         SetTMSValue(0);
  522.     else /* ( NextTAPState[CurrentTAPState][1] == NextState ) */
  523.         SetTMSValue(1);
  524.  
  525.     /* now transition the chip TAP controller to the new state */
  526.     PulseTCK();
  527.  
  528.     /* update the internal copy of the TAP controller state */
  529.     UpdateTAPState();
  530.  
  531.     /* check to make sure the current state matches what was requested */
  532.     assert( CurrentTAPState==NextState );
  533.     }
  534.  
  535. /*
  536.  * RTN GoThruTAPSequence: moves through a sequence of TAP controller states.
  537.  *
  538.  * The desired TAP controller state sequences is entered as an argument
  539.  * string terminated with a -1.
  540.  */
  541. void GoThruTAPSequence( JTAGState NextState, ... )
  542.     {
  543.     /* progress through the states until a -1 is seen */
  544.     va_list ap;
  545.     for( va_start(ap,NextState); NextState != -1;
  546.                 NextState=va_arg(ap,JTAGState) )
  547.         GotoNextTAPState( NextState );
  548.     va_end( ap );
  549.     }
  550.  
  551.  
  552.  
  553. /* BSDR and BSIR INPUT/OUTPUT SUBROUTINES */
  554.  
  555. /*
  556.  * RTN SendRcvBit: get the current bit from TDI, send a bit through TDO,
  557.  *                 and pulse TCLK.
  558.  *
  559.  * This subroutine assumes that the TCK is 0 and the TAP controller state
  560.  * is Shift-DR or Shift-IR upon entry.  That's why we pick up the value
  561.  * coming in through TDI right away.
  562.  */
  563. unsigned int SendRcvBit( unsigned SendBit )
  564.     {
  565.     unsigned int TDIValue;
  566.  
  567.     /* Make sure we are in the Shift-IR or Shift-DR state.  Gathering
  568.        and shifting out data isn't legal otherwise. */
  569.     assert( CurrentTAPState==ShiftIR || CurrentTAPState==ShiftDR );
  570.  
  571.     /* get the value on the TDI input when TCK is low */
  572.     TDIValue = GetTDIValue();
  573.  
  574.     /* now output the specified value on TDO */
  575.     SetTDOValue( SendBit & 1 );
  576.  
  577.     /* pulse TCK to move the BSIR or BSDR by one bit */
  578.     PulseTCK(); /* clock goes high then low */
  579.  
  580.     /* update the current TAP controller state */
  581.     UpdateTAPState();
  582.  
  583.     /* return the value we captured off TDI */
  584.     return TDIValue;
  585.     }
  586.  
  587. /*
  588.  * RTN SendRcvBitstream: transmit a bitstream through TDO while receiving
  589.  *                       a bitstream through TDI.
  590.  *
  591.  * This subroutine assumes the TAP controller state is
  592.  * Shift-IR or Shift-DR upon entry.  Upon termination, this subroutine
  593.  * will leave the TAP controller in the Exit1-IR or Exit1-DR state.
  594.  *
  595.  * Either SendBits or RcvBits can be NULL if you don't want to transmit
  596.  * or receive bits during a particular call to this subroutine.
  597.  * For example, you may want to load the BSDR with a bit pattern but
  598.  * you might not care what data gets shifted out of the BSDR during
  599.  * the loading.
  600.  *
  601.  * SendBits and RcvBits can point to the same bitstream without
  602.  * causing problems.
  603.  *
  604.  * Note that the LSB of a bitstream has an index of 0.
  605.  */
  606. void SendRcvBitstream( int length, bitstream *SendBits, bitstream *RcvBits )
  607.     {
  608.     int i, j, WordLength, NumWords;
  609.     bitstream SendWord;
  610.  
  611.     /* compute the number of words in the bitstream */
  612.     WordLength = 8 * sizeof(bitstream)/sizeof(char);
  613.  
  614.     /* it's nonsense to operate on a zero-length bitstream, so
  615.        abort if that's the case. */
  616.     assert( length>0 );
  617.  
  618.     /* lower the TMS line to make sure the TAP controller stays
  619.        in the Shift-IR or Shift-DR state for the first length-1 cycles */
  620.     SetTMSValue(0);
  621.  
  622.     for( i=0; i<length; i++ )
  623.         {
  624.         unsigned int sendbit, rcvbit;
  625.  
  626.         /* On the last bit, raise the TMS line so the TAP
  627.            controller will move out of the Shift state into
  628.            the Exit1 state. */
  629.         if( i==length-1 )
  630.             SetTMSValue(1);
  631.  
  632.         /* send the next bit if the bitstream is not NULL ... */
  633.         if( SendBits!=NULL )
  634.             rcvbit = SendRcvBit(GetBit(SendBits,i));
  635.         /* else just shift in a zero */
  636.         else
  637.             rcvbit = SendRcvBit(0);
  638.  
  639.         /* store the received bit if the bitstream is not NULL */
  640.         if( RcvBits!=NULL )
  641.             SetBit( RcvBits, i, rcvbit );
  642.         }
  643.     }
  644.  
  645. /*
  646.  * RTN LoadBSIRthenBSDR: load the BSIR, execute the instruction, and
  647.  *                       then capture and reload the BSDR.
  648.  *
  649.  * This subroutine assumes the TAP controller is in the Test-Logic-Reset
  650.  * or Run-Test/Idle state upon entry.  The TAP controller is returned to the
  651.  * Run-Test/Idle state upon exit.
  652.  */
  653. void LoadBSIRthenBSDR( int BSIRLength, bitstream *instruction,
  654.                int BSDRLength, bitstream *send, bitstream *recv )
  655.     {
  656.     /* move the TAP controller from the Test-Logic-Reset or
  657.        Run-Test/Idle state to the Shift-IR state */
  658.     GoThruTAPSequence( RunTestIdle, SelectDRScan,
  659.                 SelectIRScan, CaptureIR, ShiftIR, -1 );
  660.  
  661.     /* now load the opcode instruction into the BSIR and
  662.        enter the Exit1-IR state when this is done */
  663.     SendRcvBitstream( BSIRLength, instruction, NULL );
  664.  
  665.     /* now activate the instruction by entering the Update-IR state. */
  666.     GoThruTAPSequence( UpdateIR, -1 );
  667.  
  668.     /* if the BSDR length is non-zero, then select the BSDR by moving
  669.        into the Capture-DR state so that the new pin data is
  670.        parallel-loaded into the BSDR.  Then move into the
  671.        Shift-DR state so that the captured data can be shifted out
  672.        while a new pattern is shifted in. Finally, output the
  673.        newly loaded data onto the parallel output of the BSDR by moving
  674.        into the Update-DR state. */
  675.     if( BSDRLength > 0 )
  676.         {
  677.         GoThruTAPSequence( SelectDRScan, CaptureDR, ShiftDR, -1 );
  678.  
  679.         /* now shift out the captured data while
  680.            new data is shifted in */
  681.         SendRcvBitstream( BSDRLength, send, recv );
  682.  
  683.         /* output the freshly loaded data onto the parallel output
  684.            of the BSDR */
  685.         GoThruTAPSequence( UpdateDR, -1 );
  686.         }
  687.  
  688.     /* return to the idle state */
  689.     GoThruTAPSequence( RunTestIdle, -1 );
  690.     }
  691.  
  692.  
  693.  
  694. /* EPX780 JTAG INSTRUCTION SUBROUTINES */
  695.  
  696. /* JTAG public instruction opcodes for the EPX780 FPGA */
  697. typedef enum
  698.      {
  699.     EXTEST  = 0,    /* drives outputs with pre-loaded data */
  700.     SAMPLE  = 1,    /* read current pins; pre-load next pin state */
  701.     IDCODE  = 2,    /* read manufacturers ID code */
  702.     LDVECT  = 5,    /* load vector into PROGRAM shift register */
  703.     FREAD   = 6,    /* read EPROM */
  704.     SWRITE  = 15,   /* write SRAM */
  705.     SREAD   = 16,   /* read SRAM */
  706.     PORST   = 20,   /* power-on reset; restarts device architecture */
  707.     FPGM    = 21,   /* program EPROM */
  708.     HIGHZ   = 29,   /* 3-state all outputs */
  709.     UESCODE = 22,   /* shift out user-defined electronic signature code */
  710.     RADLOAD = 24,   /* load row address */
  711.     ISCAN   = 30,   /* internal scan of device */
  712.     BYPASS  = 31    /* bypass the device JTAG mechanism */
  713.      } EPX780JTAGOpcode;
  714.  
  715. #define EPX780OpcodeLength  5 /* the bit length of the EPX780 JTAG opcodes */
  716. #define EPX780IDCodeLength 32 /* Device ID code register length */
  717. #define EPX780BSDRLength  264 /* boundary-scan data register length */
  718. #define EPX780UESLength   600 /* user-electronic-signature register length */
  719.  
  720. /*
  721.  * RTN EPX780IDCode: read the manufacturer's Device ID code.
  722.  *
  723.  * The ID code is stored into the memory pointed to by DeviceIDCode.
  724.  */
  725. void EPX780IDCode( bitstream *DeviceIDCode )
  726.     {
  727.     bitstream instr = IDCODE;
  728.  
  729.     LoadBSIRthenBSDR( EPX780OpcodeLength, &instr,
  730.               EPX780IDCodeLength, NULL, DeviceIDCode );
  731.     }
  732.  
  733. /*
  734.  * RTN EPX780UES: read the user-loaded User Electronic Signature.
  735.  *
  736.  * The signature is stored into the memory pointed to by UESig.
  737.  */
  738. void EPX780UES( bitstream *UESig )
  739.     {
  740.     bitstream instr = UESCODE;
  741.  
  742.     LoadBSIRthenBSDR( EPX780OpcodeLength, &instr,
  743.               EPX780UESLength, NULL, UESig );
  744.     }
  745.  
  746. /*
  747.  * RTN EPX780SamplePreload: read current pin state and preload next state.
  748.  *
  749.  * The BSDR is loaded with the data pointed to by send and the sampled pin
  750.  * values shifted out of the BSDR are stored into the memory pointed to
  751.  * by recv.
  752.  */
  753. void EPX780SamplePreload( bitstream *send, bitstream *recv )
  754.     {
  755.     bitstream instr = SAMPLE;
  756.  
  757.     LoadBSIRthenBSDR( EPX780OpcodeLength, &instr,
  758.               EPX780BSDRLength, send, recv );
  759.     }
  760.  
  761. /*
  762.  * RTN EPX780Extest: drive outputs with preloaded data.
  763.  *
  764.  * The BSDR is loaded with the new pin values pointed to by send and the
  765.  * old pin values shifted out of the BSDR are stored into the memory
  766.  * pointed to by recv.
  767.  */
  768. void EPX780Extest( bitstream *send, bitstream *recv )
  769.     {
  770.     bitstream instr = EXTEST;
  771.  
  772.     LoadBSIRthenBSDR( EPX780OpcodeLength, &instr,
  773.               EPX780BSDRLength, send, recv );
  774.     }
  775.  
  776. /*
  777.  * RTN EPX780HighZ: tristate all the outputs.
  778.  */
  779. void EPX780HighZ(void)
  780.     {
  781.     bitstream instr = HIGHZ;
  782.  
  783.     LoadBSIRthenBSDR( EPX780OpcodeLength, &instr, 0, NULL, NULL );
  784.     }
  785.  
  786. /*
  787.  * RTN EPX780Bypass: bypass the data register.
  788.  */
  789. void EPX780Bypass(void)
  790.     {
  791.     bitstream instr = BYPASS;
  792.  
  793.     LoadBSIRthenBSDR( EPX780OpcodeLength, &instr, 0, NULL, NULL );
  794.     }
  795.  
  796.  
  797. /* EPX780 JTAG BSDR ASSIGNMENTS  */
  798.  
  799. /*
  800.  * The following enumeration is the order of the scan cells in the
  801.  * BSDR for the EPX780 FPGA (both 84-pin and 132-pin versions).
  802.  * We got this from the I780_84.BSD file included with PLDshell.
  803.  * The list starts with the LSB and ends with the MSB of the scan path.
  804.  * Each macrocell scan cell has three bits associated with it: an
  805.  * OE cell which enables the tristate buffer when set to 1, an OUT cell
  806.  * whose value is output on the pin when the tristate buffer is enabled,
  807.  * and an IN cell which captures the value placed on the pin.
  808.  * The CLK1 and CLK2 scan cells are able to capture the values on the clock
  809.  * inputs.  The IN0..IN21 scan cells can capture the values on the
  810.  * dedicated inputs, but these inputs exist only on the 132-pin
  811.  * version of the EPX780, not on the 84-pin version.
  812.  */
  813. typedef enum {
  814.     IO09OE, IO09OUT, IO09IN,
  815.     IO08OE, IO08OUT, IO08IN,
  816.     IO07OE, IO07OUT, IO07IN,
  817.     IO06OE, IO06OUT, IO06IN,
  818.     IO05OE, IO05OUT, IO05IN,
  819.     IO04OE, IO04OUT, IO04IN,
  820.     IO03OE, IO03OUT, IO03IN,
  821.     IO02OE, IO02OUT, IO02IN,
  822.     IO01OE, IO01OUT, IO01IN,
  823.     IO00OE, IO00OUT, IO00IN,
  824.     CLK1,
  825.     IO10OE, IO10OUT, IO10IN,
  826.     IO11OE, IO11OUT, IO11IN,
  827.     IO12OE, IO12OUT, IO12IN,
  828.     IO13OE, IO13OUT, IO13IN,
  829.     IO14OE, IO14OUT, IO14IN,
  830.     IO15OE, IO15OUT, IO15IN,
  831.     IO16OE, IO16OUT, IO16IN,
  832.     IO17OE, IO17OUT, IO17IN,
  833.     IO18OE, IO18OUT, IO18IN,
  834.     IO19OE, IO19OUT, IO19IN,
  835.     IN0, IN1, IN2, IN3, IN4, IN5,
  836.     IO39OE, IO39OUT, IO39IN,
  837.     IO38OE, IO38OUT, IO38IN,
  838.     IO37OE, IO37OUT, IO37IN,
  839.     IO36OE, IO36OUT, IO36IN,
  840.     IO35OE, IO35OUT, IO35IN,
  841.     IO34OE, IO34OUT, IO34IN,
  842.     IO33OE, IO33OUT, IO33IN,
  843.     IO32OE, IO32OUT, IO32IN,
  844.     IO31OE, IO31OUT, IO31IN,
  845.     IO30OE, IO30OUT, IO30IN,
  846.     IO50OE, IO50OUT, IO50IN,
  847.     IO51OE, IO51OUT, IO51IN,
  848.     IO52OE, IO52OUT, IO52IN,
  849.     IO53OE, IO53OUT, IO53IN,
  850.     IO54OE, IO54OUT, IO54IN,
  851.     IO55OE, IO55OUT, IO55IN,
  852.     IO56OE, IO56OUT, IO56IN,
  853.     IO57OE, IO57OUT, IO57IN,
  854.     IO58OE, IO58OUT, IO58IN,
  855.     IO59OE, IO59OUT, IO59IN,
  856.     IN6, IN7, IN8, IN9, IN10,
  857.     IO79OE, IO79OUT, IO79IN,
  858.     IO78OE, IO78OUT, IO78IN,
  859.     IO77OE, IO77OUT, IO77IN,
  860.     IO76OE, IO76OUT, IO76IN,
  861.     IO75OE, IO75OUT, IO75IN,
  862.     IO74OE, IO74OUT, IO74IN,
  863.     IO73OE, IO73OUT, IO73IN,
  864.     IO72OE, IO72OUT, IO72IN,
  865.     IO71OE, IO71OUT, IO71IN,
  866.     IO70OE, IO70OUT, IO70IN,
  867.     CLK2,
  868.     IO60OE, IO60OUT, IO60IN,
  869.     IO61OE, IO61OUT, IO61IN,
  870.     IO62OE, IO62OUT, IO62IN,
  871.     IO63OE, IO63OUT, IO63IN,
  872.     IO64OE, IO64OUT, IO64IN,
  873.     IO65OE, IO65OUT, IO65IN,
  874.     IO66OE, IO66OUT, IO66IN,
  875.     IO67OE, IO67OUT, IO67IN,
  876.     IO68OE, IO68OUT, IO68IN,
  877.     IO69OE, IO69OUT, IO69IN,
  878.     IN11, IN12, IN13, IN14, IN15, IN16,
  879.     IO49OE, IO49OUT, IO49IN,
  880.     IO48OE, IO48OUT, IO48IN,
  881.     IO47OE, IO47OUT, IO47IN,
  882.     IO46OE, IO46OUT, IO46IN,
  883.     IO45OE, IO45OUT, IO45IN,
  884.     IO44OE, IO44OUT, IO44IN,
  885.     IO43OE, IO43OUT, IO43IN,
  886.     IO42OE, IO42OUT, IO42IN,
  887.     IO41OE, IO41OUT, IO41IN,
  888.     IO40OE, IO40OUT, IO40IN,
  889.     IO20OE, IO20OUT, IO20IN,
  890.     IO21OE, IO21OUT, IO21IN,
  891.     IO22OE, IO22OUT, IO22IN,
  892.     IO23OE, IO23OUT, IO23IN,
  893.     IO24OE, IO24OUT, IO24IN,
  894.     IO25OE, IO25OUT, IO25IN,
  895.     IO26OE, IO26OUT, IO26IN,
  896.     IO27OE, IO27OUT, IO27IN,
  897.     IO28OE, IO28OUT, IO28IN,
  898.     IO29OE, IO29OUT, IO29IN,
  899.     IN17, IN18, IN19, IN20, IN21
  900.     } EPX780ScanPosition;
  901.  
  902.  
  903. /*
  904.  * The following array lets us recall the names for each scan cell in the
  905.  * EPX780 BSDR.
  906.  */
  907. static char *EPX780ScanPosNames[] = {
  908.     "IO09OE", "IO09OUT", "IO09IN",
  909.     "IO08OE", "IO08OUT", "IO08IN",
  910.     "IO07OE", "IO07OUT", "IO07IN",
  911.     "IO06OE", "IO06OUT", "IO06IN",
  912.     "IO05OE", "IO05OUT", "IO05IN",
  913.     "IO04OE", "IO04OUT", "IO04IN",
  914.     "IO03OE", "IO03OUT", "IO03IN",
  915.     "IO02OE", "IO02OUT", "IO02IN",
  916.     "IO01OE", "IO01OUT", "IO01IN",
  917.     "IO00OE", "IO00OUT", "IO00IN",
  918.     "CLK1",
  919.     "IO10OE", "IO10OUT", "IO10IN",
  920.     "IO11OE", "IO11OUT", "IO11IN",
  921.     "IO12OE", "IO12OUT", "IO12IN",
  922.     "IO13OE", "IO13OUT", "IO13IN",
  923.     "IO14OE", "IO14OUT", "IO14IN",
  924.     "IO15OE", "IO15OUT", "IO15IN",
  925.     "IO16OE", "IO16OUT", "IO16IN",
  926.     "IO17OE", "IO17OUT", "IO17IN",
  927.     "IO18OE", "IO18OUT", "IO18IN",
  928.     "IO19OE", "IO19OUT", "IO19IN",
  929.     "IN0", "IN1", "IN2", "IN3", "IN4", "IN5",
  930.     "IO39OE", "IO39OUT", "IO39IN",
  931.     "IO38OE", "IO38OUT", "IO38IN",
  932.     "IO37OE", "IO37OUT", "IO37IN",
  933.     "IO36OE", "IO36OUT", "IO36IN",
  934.     "IO35OE", "IO35OUT", "IO35IN",
  935.     "IO34OE", "IO34OUT", "IO34IN",
  936.     "IO33OE", "IO33OUT", "IO33IN",
  937.     "IO32OE", "IO32OUT", "IO32IN",
  938.     "IO31OE", "IO31OUT", "IO31IN",
  939.     "IO30OE", "IO30OUT", "IO30IN",
  940.     "IO50OE", "IO50OUT", "IO50IN",
  941.     "IO51OE", "IO51OUT", "IO51IN",
  942.     "IO52OE", "IO52OUT", "IO52IN",
  943.     "IO53OE", "IO53OUT", "IO53IN",
  944.     "IO54OE", "IO54OUT", "IO54IN",
  945.     "IO55OE", "IO55OUT", "IO55IN",
  946.     "IO56OE", "IO56OUT", "IO56IN",
  947.     "IO57OE", "IO57OUT", "IO57IN",
  948.     "IO58OE", "IO58OUT", "IO58IN",
  949.     "IO59OE", "IO59OUT", "IO59IN",
  950.     "IN6", "IN7", "IN8", "IN9", "IN10",
  951.     "IO79OE", "IO79OUT", "IO79IN",
  952.     "IO78OE", "IO78OUT", "IO78IN",
  953.     "IO77OE", "IO77OUT", "IO77IN",
  954.     "IO76OE", "IO76OUT", "IO76IN",
  955.     "IO75OE", "IO75OUT", "IO75IN",
  956.     "IO74OE", "IO74OUT", "IO74IN",
  957.     "IO73OE", "IO73OUT", "IO73IN",
  958.     "IO72OE", "IO72OUT", "IO72IN",
  959.     "IO71OE", "IO71OUT", "IO71IN",
  960.     "IO70OE", "IO70OUT", "IO70IN",
  961.     "CLK2",
  962.     "IO60OE", "IO60OUT", "IO60IN",
  963.     "IO61OE", "IO61OUT", "IO61IN",
  964.     "IO62OE", "IO62OUT", "IO62IN",
  965.     "IO63OE", "IO63OUT", "IO63IN",
  966.     "IO64OE", "IO64OUT", "IO64IN",
  967.     "IO65OE", "IO65OUT", "IO65IN",
  968.     "IO66OE", "IO66OUT", "IO66IN",
  969.     "IO67OE", "IO67OUT", "IO67IN",
  970.     "IO68OE", "IO68OUT", "IO68IN",
  971.     "IO69OE", "IO69OUT", "IO69IN",
  972.     "IN11", "IN12", "IN13", "IN14", "IN15", "IN16",
  973.     "IO49OE", "IO49OUT", "IO49IN",
  974.     "IO48OE", "IO48OUT", "IO48IN",
  975.     "IO47OE", "IO47OUT", "IO47IN",
  976.     "IO46OE", "IO46OUT", "IO46IN",
  977.     "IO45OE", "IO45OUT", "IO45IN",
  978.     "IO44OE", "IO44OUT", "IO44IN",
  979.     "IO43OE", "IO43OUT", "IO43IN",
  980.     "IO42OE", "IO42OUT", "IO42IN",
  981.     "IO41OE", "IO41OUT", "IO41IN",
  982.     "IO40OE", "IO40OUT", "IO40IN",
  983.     "IO20OE", "IO20OUT", "IO20IN",
  984.     "IO21OE", "IO21OUT", "IO21IN",
  985.     "IO22OE", "IO22OUT", "IO22IN",
  986.     "IO23OE", "IO23OUT", "IO23IN",
  987.     "IO24OE", "IO24OUT", "IO24IN",
  988.     "IO25OE", "IO25OUT", "IO25IN",
  989.     "IO26OE", "IO26OUT", "IO26IN",
  990.     "IO27OE", "IO27OUT", "IO27IN",
  991.     "IO28OE", "IO28OUT", "IO28IN",
  992.     "IO29OE", "IO29OUT", "IO29IN",
  993.     "IN17", "IN18", "IN19", "IN20", "IN21"
  994.     };
  995.  
  996. /*
  997.  * The following array gives the positions in the BSDR bitstream for
  998.  * all the macrocell scan cells.  Each macrocell is a bidirectional I/O
  999.  * pin and so has three associated scan cells: one for controlling the
  1000.  * tristate buffer, one for output, and one for input. You can get the
  1001.  * position of any macrocell scan cell in the BSDR by indexing this array
  1002.  * with the index of the macrocell and the index of the output enable, output,
  1003.  * or input cell you want.
  1004.  */
  1005. #define OE  0   /* first column lists tristate control scan cell positions */
  1006. #define OUT 1   /* next column lists output scan cell positions */
  1007. #define IN  2   /* last column lists input scan cell positions */
  1008.  
  1009. int EPX780MacrocellPosition[][3] =
  1010.     {
  1011.     /* CFB 0 macrocells */
  1012.     { IO00OE, IO00OUT, IO00IN },
  1013.     { IO01OE, IO01OUT, IO01IN },
  1014.     { IO02OE, IO02OUT, IO02IN },
  1015.     { IO03OE, IO03OUT, IO03IN },
  1016.     { IO04OE, IO04OUT, IO04IN },
  1017.     { IO05OE, IO05OUT, IO05IN },
  1018.     { IO06OE, IO06OUT, IO06IN },
  1019.     { IO07OE, IO07OUT, IO07IN },
  1020.     { IO08OE, IO08OUT, IO08IN },
  1021.     { IO09OE, IO09OUT, IO09IN },
  1022.     /* CFB 1 macrocells */
  1023.     { IO10OE, IO10OUT, IO10IN },
  1024.     { IO11OE, IO11OUT, IO11IN },
  1025.     { IO12OE, IO12OUT, IO12IN },
  1026.     { IO13OE, IO13OUT, IO13IN },
  1027.     { IO14OE, IO14OUT, IO14IN },
  1028.     { IO15OE, IO15OUT, IO15IN },
  1029.     { IO16OE, IO16OUT, IO16IN },
  1030.     { IO17OE, IO17OUT, IO17IN },
  1031.     { IO18OE, IO18OUT, IO18IN },
  1032.     { IO19OE, IO19OUT, IO19IN },
  1033.     /* CFB 2 macrocells */
  1034.     { IO20OE, IO20OUT, IO20IN },
  1035.     { IO21OE, IO21OUT, IO21IN },
  1036.     { IO22OE, IO22OUT, IO22IN },
  1037.     { IO23OE, IO23OUT, IO23IN },
  1038.     { IO24OE, IO24OUT, IO24IN },
  1039.     { IO25OE, IO25OUT, IO25IN },
  1040.     { IO26OE, IO26OUT, IO26IN },
  1041.     { IO27OE, IO27OUT, IO27IN },
  1042.     { IO28OE, IO28OUT, IO28IN },
  1043.     { IO29OE, IO29OUT, IO29IN },
  1044.     /* CFB 3 macrocells */
  1045.     { IO30OE, IO30OUT, IO30IN },
  1046.     { IO31OE, IO31OUT, IO31IN },
  1047.     { IO32OE, IO32OUT, IO32IN },
  1048.     { IO33OE, IO33OUT, IO33IN },
  1049.     { IO34OE, IO34OUT, IO34IN },
  1050.     { IO35OE, IO35OUT, IO35IN },
  1051.     { IO36OE, IO36OUT, IO36IN },
  1052.     { IO37OE, IO37OUT, IO37IN },
  1053.     { IO38OE, IO38OUT, IO38IN },
  1054.     { IO39OE, IO39OUT, IO39IN },
  1055.     /* CFB 4 macrocells */
  1056.     { IO40OE, IO40OUT, IO40IN },
  1057.     { IO41OE, IO41OUT, IO41IN },
  1058.     { IO42OE, IO42OUT, IO42IN },
  1059.     { IO43OE, IO43OUT, IO43IN },
  1060.     { IO44OE, IO44OUT, IO44IN },
  1061.     { IO45OE, IO45OUT, IO45IN },
  1062.     { IO46OE, IO46OUT, IO46IN },
  1063.     { IO47OE, IO47OUT, IO47IN },
  1064.     { IO48OE, IO48OUT, IO48IN },
  1065.     { IO49OE, IO49OUT, IO49IN },
  1066.     /* CFB 5 macrocells */
  1067.     { IO50OE, IO50OUT, IO50IN },
  1068.     { IO51OE, IO51OUT, IO51IN },
  1069.     { IO52OE, IO52OUT, IO52IN },
  1070.     { IO53OE, IO53OUT, IO53IN },
  1071.     { IO54OE, IO54OUT, IO54IN },
  1072.     { IO55OE, IO55OUT, IO55IN },
  1073.     { IO56OE, IO56OUT, IO56IN },
  1074.     { IO57OE, IO57OUT, IO57IN },
  1075.     { IO58OE, IO58OUT, IO58IN },
  1076.     { IO59OE, IO59OUT, IO59IN },
  1077.     /* CFB 6 macrocells */
  1078.     { IO60OE, IO60OUT, IO60IN },
  1079.     { IO61OE, IO61OUT, IO61IN },
  1080.     { IO62OE, IO62OUT, IO62IN },
  1081.     { IO63OE, IO63OUT, IO63IN },
  1082.     { IO64OE, IO64OUT, IO64IN },
  1083.     { IO65OE, IO65OUT, IO65IN },
  1084.     { IO66OE, IO66OUT, IO66IN },
  1085.     { IO67OE, IO67OUT, IO67IN },
  1086.     { IO68OE, IO68OUT, IO68IN },
  1087.     { IO69OE, IO69OUT, IO69IN },
  1088.     /* CFB 7 macrocells */
  1089.     { IO70OE, IO70OUT, IO70IN },
  1090.     { IO71OE, IO71OUT, IO71IN },
  1091.     { IO72OE, IO72OUT, IO72IN },
  1092.     { IO73OE, IO73OUT, IO73IN },
  1093.     { IO74OE, IO74OUT, IO74IN },
  1094.     { IO75OE, IO75OUT, IO75IN },
  1095.     { IO76OE, IO76OUT, IO76IN },
  1096.     { IO77OE, IO77OUT, IO77IN },
  1097.     { IO78OE, IO78OUT, IO78IN },
  1098.     { IO79OE, IO79OUT, IO79IN },
  1099.     };
  1100.  
  1101. /*
  1102.  * This is similar to the previous array.  It lets you get the position
  1103.  * in the BSDR for the scan cells associated with the clock inputs.
  1104.  */
  1105. int EPX780ClockPosition[] =
  1106.     {
  1107.     -1, CLK1, CLK2
  1108.     };
  1109.  
  1110. /*
  1111.  * This is similar to the previous arrays.  It lets you get the position
  1112.  * in the BSDR for the scan cells associated with the dedicated inputs.
  1113.  */
  1114. int EPX780InputPosition[] =
  1115.     {
  1116.       IN0,  IN1,  IN2,  IN3,  IN4,  IN5,  IN6,  IN7,  IN8,  IN9,
  1117.       IN10, IN11, IN12, IN13, IN14, IN15, IN16, IN17, IN18, IN19,
  1118.       IN20, IN21
  1119.     };
  1120.  
  1121.  
  1122. /*
  1123.  * RTN SetMacrocellDirection: sets the given macrocell (0..79) to be
  1124.  *                            an output (dir=1) or an input (dir=0).
  1125.  */
  1126. void SetMacrocellDirection( bitstream *bsdr, int macrocell, int dir )
  1127.     {
  1128.     SetBit( bsdr, EPX780MacrocellPosition[macrocell][OE], dir );
  1129.     }
  1130.  
  1131. /*
  1132.  * RTN GetMacrocellDirection: returns the IO setting for the macrocell.
  1133.  */
  1134. int GetMacrocellDirection( bitstream *bsdr, int macrocell )
  1135.     {
  1136.     return GetBit( bsdr, EPX780MacrocellPosition[macrocell][OE] );
  1137.     }
  1138.  
  1139. /*
  1140.  * RTN SetMacrocellOutput: sets the value stored in the output cell of
  1141.  *                         the BSDR for the given macrocell (0..79).
  1142.  */
  1143. void SetMacrocellOutput( bitstream *bsdr, int macrocell, int value )
  1144.     {
  1145.     SetBit( bsdr, EPX780MacrocellPosition[macrocell][OUT], value );
  1146.     }
  1147.  
  1148. /*
  1149.  * RTN GetMacrocellOutput: gets the value stored in the output cell of
  1150.  *                         the BSDR for the given macrocell (0..79).
  1151.  */
  1152. int GetMacrocellOutput( bitstream *bsdr, int macrocell )
  1153.     {
  1154.     return GetBit( bsdr, EPX780MacrocellPosition[macrocell][OUT] );
  1155.     }
  1156.  
  1157. /*
  1158.  * RTN SetMacrocellInput: sets the value stored in the input cell of
  1159.  *                         the BSDR for the given macrocell (0..79).
  1160.  */
  1161. void SetMacrocellInput( bitstream *bsdr, int macrocell, int value )
  1162.     {
  1163.     SetBit( bsdr, EPX780MacrocellPosition[macrocell][IN], value );
  1164.     }
  1165.  
  1166. /*
  1167.  * RTN GetMacrocellInput: gets the value stored in the input cell of
  1168.  *                         the BSDR for the given macrocell (0..79).
  1169.  */
  1170. int GetMacrocellInput( bitstream *bsdr, int macrocell )
  1171.     {
  1172.     return GetBit( bsdr, EPX780MacrocellPosition[macrocell][IN] );
  1173.     }
  1174.  
  1175. /*
  1176.  * RTN SetSyncClock: Sets the value stored in the input cell of
  1177.  *                   the BSDR for the given synchronous clock input (1..2).
  1178.  */
  1179. void SetSyncCLOCK( bitstream *bsdr, int clock, int value )
  1180.     {
  1181.     SetBit( bsdr, EPX780ClockPosition[clock], value );
  1182.     }
  1183.  
  1184. /*
  1185.  * RTN GetSyncClock: gets the value stored in the input cell of
  1186.  *                   the BSDR for the given synchronous clock input (1..2).
  1187.  */
  1188. int GetSyncClock( bitstream *bsdr, int clock )
  1189.     {
  1190.     return GetBit( bsdr, EPX780ClockPosition[clock] );
  1191.     }
  1192.  
  1193. /*
  1194.  * RTN SetDedicatedInput: Sets the value stored in the input cell of the
  1195.  *                        BSDR for the given dedicated input (0..21).
  1196.  */
  1197. void SetDedicatedInput( bitstream *bsdr, int input, int value )
  1198.     {
  1199.     return SetBit( bsdr, EPX780InputPosition[input], value );
  1200.     }
  1201.  
  1202. /*
  1203.  * RTN GetDedicatedInput: Gets the value stored in the input cell of the
  1204.  *                        BSDR for the given dedicated input (0..21).
  1205.  */
  1206. int GetDedicatedInput( bitstream *bsdr, int input )
  1207.     {
  1208.     return GetBit( bsdr, EPX780InputPosition[input] );
  1209.     }
  1210.  
  1211.